function f_check_mode_opt()
{
    declare update_state fun_name sql
    fun_name="f_check_mode_opt"
    update_state=0
    if [ "${mode_opt}x" == "crontab_taskx" ]
    then

        sleep $((${RANDOM}%3+1)).$((${RANDOM}%1000+1)) || true #添加一个暂停时间, 只要是控制多个节点不同时执行

        sql="update ${t_cront_task} set istate = -1 
                 where (order_id,mysql_port) in (select order_id,port from  ${t_order_info} where progress = \"定时任务, 尚未开始\" and run_state = -1);
             update ${t_order_info} set run_state=-1,u_time=now() , remarks = \"业务手动终止\"
                 where progress = \"定时任务, 尚未开始\" and run_state = -1 and remarks != \"审批人驳回\""

        f_logging "$(eval echo ${log_addr}):INFO" "${sql}"
        ${mysql_comm_dbadb} -NBe "${sql}" 2>/dev/null || true

        #开始改表前先将业务审批人驳回的工单过滤掉
        sql="update ${t_cront_task} set inip = '${localhost_ip}' where istate = 2 and inip = '';select concat(id,':::',order_id,':::',u_name,':::',command,':::',mysql_port,':::',db_name) from ${t_cront_task} 
            where istate = 2 and exe_date = '$(date +%F)' and start_hour <= $(date +%H) 
            and order_id not in (select order_id from  ${t_order_info} where progress = '定时任务, 尚未开始' and run_state = -1) and inip = '${localhost_ip}';"

        ${mysql_comm_dbadb} -NBe "${sql}" 2>/dev/null|while read line
        do
            com_id="$(awk -F':::' '{print $1}' <<< "${line}")"
            order_id="$(awk -F':::' '{print $2}' <<< "${line}")"
            user_order_id=${order_id}
            u_name="$(awk -F':::' '{print $3}' <<< "${line}")"
            sql="update ${t_cront_task} set istate = 1 where istate = 2 and id = ${com_id} and inip = '${localhost_ip}'"
            f_logging "$(eval echo ${log_addr}):INFO" "${sql}"
            ${mysql_comm_dbadb} -NBe "${sql}" 2>/dev/null || true
            com_info="$(awk -F':::' '{print $4}' <<< "${line}")"
            mysql_port="$(awk -F':::' '{print $5}' <<< "${line}")"
            db_name="$(awk -F':::' '{print $6}' <<< "${line}")"
            env="测试环境"
            if [ "$(grep -c -- "-d dev" <<< "${com_info}")x" == "0x" ]
            then
                env="线上环境"
            fi
            curl_url="${alert_url}?user=${u_name}&type=wx&url=${link_url}"

            if [ "$(grep -c -- "-e 0" <<< "${com_info}")x" == "0x" ]
            then #定时任务预执行, 所以不用管工单详情表的记录
                sql="delete from ${t_order_info} where progress = '定时任务, 尚未开始' and order_id = ${order_id};"
                f_logging "$(eval echo ${log_addr}):INFO" "${sql}"
                ${mysql_comm_dbadb} -NBe "${sql}" 2>/dev/null || true
                info="$(date "+%F %T");工单号:${order_id}(${env});端口号:${mysql_port};数据库名:${db_name};工单状态:即将开始(这是提示信息, 可以忽略)"
                curl -XGET --data-urlencode "info=${info}" "${curl_url}" || true
            fi
            eval ${com_info}
        done

        #end_hour < 23表示这个任务不设置执行区间, 就是说这个任务是开始到结束, 中间不用暂停
        ${mysql_comm_dbadb} -NBe "select concat(order_id,':::',start_hour,':::',end_hour,':::',mysql_port) from ${t_cront_task} where istate = 1 and end_hour < 25" 2>/dev/null|while read line 
        do
            w_id="$(awk -F':::' '{print $1}' <<< "${line}")"
            user_order_id=${w_id}
            start_hour="$(awk -F':::' '{print $2}' <<< "${line}")"
            end_hour="$(awk -F':::' '{print $3}' <<< "${line}")"
            m_port="$(awk -F':::' '{print $4}' <<< "${line}")"
            if [ "${start_hour}x" == "${end_hour}x" ]
            then
                if [ "$(date +%H)x" == "${start_hour}x" ]
                then #当前时间等于开始时间或者等于结束时间就是执行时间, 此时间外就是暂停
                    istate=0
                else
                    istate=1
                fi
            elif [ "${start_hour}" -lt "${end_hour}" ]
            then #开始时间(数值)小于结束时间, 比如0-6
                if [ "$(date +%H)" -ge "${start_hour}" -a "$(date +%H)" -le "${end_hour}" ]
                then #当前时间大于等于开始时间且小于等于结束时间就是正常改表
                    istate=0
                else
                    istate=1
                fi
            else #开始时间大于结束时间比如23-6
                if [ "$(date +%H)" -ge "${end_hour}" -a "$(date +%H)" -le "${start_hour}" ]
                then
                    istate=1
                else
                    istate=0
                fi
            fi
            sql="update ${t_state_task} set run_state = ${istate} where order_id = ${w_id} and port = ${m_port} and remarks = '临时记录工单完成会删除';"
            f_logging "$(eval echo ${log_addr}):INFO" "${sql}"
            ${mysql_comm_dbadb} -NBe "${sql}" 2>/dev/null || true
        done

        #5min没有更新工单状态的工单视为异常
        ${mysql_comm_dbadb} -NBe "select concat(order_id,':::',user_mail,':::',id) from ${t_order_info} where u_time < date_add(now(), INTERVAL - 30 MINUTE) and run_state = 0;" 2>/dev/null |while read line 
        do
            w_id="$(awk -F':::' '{print $1}' <<< "${line}")"
            user_order_id=${w_id}
            u_name="$(awk -F':::' '{print $2}' <<< "${line}")"
            p_id="$(awk -F':::' '{print $3}' <<< "${line}")"
            sql="update ${t_order_info} set run_state = -1, u_time = now(),remarks = concat(remarks,',','工单状态监控异常, 可能实际还在继续改表, 可以观察一段时间然后联系dba') where order_id = ${w_id} and id = ${p_id}"
            f_logging "$(eval echo ${log_addr}):INFO" "${sql}"
            ${mysql_comm_dbadb} -NBe "${sql}" 2>/dev/null || true
            f_logging "$(eval echo ${log_addr}):ERROR" "改表工单:30min未变更状态;工单号:${w_id}"
            curl -XGET --data-urlencode "info=$(date "+%F %T");改表工单:执行异常;工单号:${w_id}" "${curl_url}" || true
        done
        exit 0
    elif [ "${mode_opt}x" == "start_taskx" ]
    then
        f_update_status_for_task_from_api "run_state = 0" "继续改表" || update_state=1
    elif [ "${mode_opt}x" == "stop_taskx" ]
    then
        f_update_status_for_task_from_api "run_state = -1" "终止改表" || update_state=1
    elif [ "${mode_opt}x" == "pause_taskx" ]
    then
        f_update_status_for_task_from_api "run_state = 1" "暂停改表" || update_state=1
    elif [ "${mode_opt}x" == "chunk_sizex" ]
    then
        f_update_status_for_task_from_api "chunk_size = ${update_number}" "修改chunk size" || update_state=1
    elif [ "${mode_opt}x" == "repl_timex" ]
    then
        f_update_status_for_task_from_api "repl_time = ${update_number}" "修改最大延迟时间" || update_state=1
    elif [ "${mode_opt}x" == "big_tablex" ]
    then
        f_update_status_for_task_from_api "big_table = 1" "修改表大小不受500GB限制" "insert" "1,0,0" || update_state=1          #1表示big_table, 0 表示disk_space
    elif [ "${mode_opt}x" == "disk_spacex" ]
    then
        f_update_status_for_task_from_api "disk_space = 1" "修改磁盘空间不受2倍表大小限制" "insert" "0,1,0" || update_state=1   #0表示big_table, 1 表示disk_space
    elif [ "${mode_opt}x" == "get_progressx" ]
    then
        f_update_status_for_task_from_api "progress" "获取改表进度" "select" "0,0,0" || update_state=1     #获取进度
    elif [ "${mode_opt}x" == "osc_toolx" ]
    then
        f_update_status_for_task_from_api "osc_tool = 1" "修改改表使用工具" "insert" "0,0,1" || update_state=1     #修改osc工具, 该端口下的所有工单都使用pt
    elif [ "${mode_opt}x" == "unique_keyx" ]
    then
        f_update_status_for_task_from_api "unique_key = 1" "修改允许添加唯一索引" && exit 0 || exit 1     #默认不允许添加唯一索引，存在风险
    else
        if [ -f "${sql_file}" ]
        then #如果不存在文件就说明是drop或者truncate动作, sql文件只是针对create|alter操作
            [ -z "${mode_opt}" ] && mode_opt="$(awk -F/ '{print $NF}' <<< "${sql_file}"|awk -F. '{print $1}')"     #判断是alter|create, 这里主要是以命令行参数优先
            mysql_db="$(awk -F/ '{print $NF}' <<< "${sql_file}"|awk -F. '{print $2}')"     #获取操作的db
            mysql_port="$(awk -F/ '{print $NF}' <<< "${sql_file}"|awk -F. '{print $3}')"   #获取端口号
            order_applytime="$(awk -F/ '{print $NF}' <<< "${sql_file}"|awk -F. '{print $4}')"   #获取工单申请时间
            order_applytime="$(date -d @${order_applytime} "+%F %H:%M:%S" 2>/dev/null)" || true
        fi
        
        _mysql_db_="\`${mysql_db}\`"    #给库名添加反引号, 防止用户的库名带中划线或者保留字
        
        if [ "${mode_opt}x" == "crontab_dropx" ]
        then
            f_logging "$(eval echo ${log_addr}):WARN" "本次操作是处理延迟删除遗留的待删除的任务" "2"
        elif [ ! -f "${sql_file}" ] && [ -z "${clear_table_list}" ]
        then
            f_logging "$(eval echo ${log_addr}):ERROR" "从 '${src_host}:/${sql_file}' 拉取sql文件成功, 但是文件 '${sql_file_dir}/${sql_file}' 不存在" "2" "1"
        elif [ ! -s "${sql_file}" ] && [ "$(grep -iPc "^(create|alter)_table" <<< "${mode_opt}")x" == "1x" ]
        then
            f_logging "$(eval echo ${log_addr}):ERROR" "'${sql_file_dir}/${sql_file}' 是空文件" "2" "1"
        elif [ ! -f "${sql_file}" ]
        then
            sql_file="$(awk -F'@' '{print $1}' <<< "${user_mail_addr}")_${user_order_id}"
            f_logging "$(eval echo ${log_addr}):WARN" "本次操作是drop|truncate table" "2"
        fi
        
        #本次操作保存的日志, 是'sql文件名.log'
        log_file="${script_execute_res_log_dir}/$(awk -F/ '{print $NF}' <<< "${sql_file}").log"
        f_logging "$(eval echo ${log_addr}):REMAIND" "开始执行 : '${s_n} ${*}' ] [ 本次操作日志, 详情请看 : ${log_file}"
        [ -n "${src_host}" ] && f_logging "$(eval echo ${log_addr}):REMAIND" "从 '${src_host}' 拉取sql文件保存在 '${sql_file}'"

        update_state=100
    fi
    return ${update_state}
}

function f_prepare()
{
    declare fun_name
    fun_name="f_prepare"
    if [ "$(grep -ic "^create_table" <<< "${mode_opt}")x" == "1x" ]
    then
        [ "${execute}x" == "1x" ] && test_db="${test_db_exe}"
        f_get_create_sql
    elif [ "$(grep -ic "^alter_table" <<< "${mode_opt}")x" == "1x" ]
    then
        f_get_diy_info || true
        if [ "${execute}x" == "0x" ] && [ "${ghost_to_ptosc}x" == "0x" ]
        then
            f_return_alter_sql
            f_get_alter_sql
        fi
        f_check_osc_or_alter && return ${?} || return ${?}
    elif [ "$(grep -ic "^drop_table" <<< "${mode_opt}")x" == "1x" ]
    then
        #f_clear_table "drop table" #删除工单统一使用rename的操作
        f_clear_table "rename table"
    elif [ "$(grep -ic "^later_drop_table" <<< "${mode_opt}")x" == "1x" ]
    then
        f_clear_table "rename table" "later"
    elif [ "$(grep -ic "^truncate_table" <<< "${mode_opt}")x" == "1x" ]
    then
        f_clear_table "truncate table"
    elif [ "$(grep -ic "^later_truncate_table" <<< "${mode_opt}")x" == "1x" ]
    then
        f_clear_table "truncate table" "later"
    elif [ "$(grep -ic "^recover" <<< "${mode_opt}")x" == "1x" ]
    then
        f_clear_table "recover"
    elif [ "$(grep -ic "^crontab_drop" <<< "${mode_opt}")x" == "1x" ]
    then
        f_clear_table "crontab_drop"
    else
        f_logging "$(eval echo ${log_addr}):WARN" "暂时不支持这种操作 '${mode_opt}'" "2" "1"
    fi
    return 0
}
